// Overseer.h

#ifdef _WIN32 
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#endif

#ifndef _ENV_OVERSEER_
#define _ENV_OVERSEER_

// Project includes
#include "DropletGlobals.h"
#include "DropletThread.h"
#include "DropletData.h"
#include "Message.h"
#include "Polynomial1Var.h"

#ifdef _WIN32
#include "inttypes.h"
#include <Windows.h>
#else
#include <inttypes.h>
#endif

// STL includes
#include <iostream>
#include <cstdlib>
#include <deque>
#include <map>
#include <cstring>
#include <math.h>
#include <time.h>

// PThreads_Win32 files
#include <semaphore.h>
#include <pthread.h>

#define MIN_DISTANCE_TOL 0.01
#define X_MIN 0.0
#define Y_MIN 0.0
#define X_MAX 10000.0
#define Y_MAX 10000.0

// ---
// This section will be removed eventually, once I have the setup project working
#define NUM_ROBOTS 5
#define LOAD_PROGRAM 1
#define FLOOR_POWER 5.0
#define X_STEP 1.0
#define Y_STEP 1.0
#define X_START ( X_MIN + X_STEP )
#define Y_START ( Y_MIN + Y_STEP )
// ---

namespace Droplets
{
	class Overseer
	{
	private :

		//Droplets::Global *globals;
		pthread_t *robotThreads;
		pthread_t controlThread;
		uint16_t *robotIDS;
		int numRobots;
		float powFloor;
		Polynomial1Var *walls;	// Array of polynomials that represent walls
								// on the map
		bool killSwitch;

		void Stop();	// Stops the simulator and performs exit cleanup
		void LoopTillStop();
		
		static void *ControlLoop(void *args);
		
		// Helper functions
		void MoveRobots();
		void OrganizeMessages();
		void BoundPos(Droplets::DropletStateData *sPtr);
		void SetupGlobals();

	public:
		Overseer();
		~Overseer();

		void Start();	// Starts the Simulator
	};
}

#endif